package org.girllee.mds.service;


import org.girllee.mds.dao.domain.mysql.TempTx;
import org.girllee.mds.dao.mapper.mysql.TempTxMapper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

/**
 *  需要抛出RuntimeException否则会发生@Transactional不起作用
 *  如不使用try catch 则会抛出 java.lang.ArithmeticException: / by zero
 *  此异常也是一个RuntimeException,由于没有处理，会一直往上抛，到JVM
 *  详细请查看
 * @see Transactional
 *
 * 可知，其默认
 */
@Service
public class MySQLTxService {


    @Resource
    TempTxMapper tempTxMapper;

    /**
     *
     * @param fromUserId
     * @param targetUserId
     * @param count
     */

    @Transactional
    public void transfer(Long fromUserId, Long targetUserId, int count) {
       xx(fromUserId,targetUserId,count);
    }

    @Transactional
    public void xx (Long fromUserId, Long targetUserId, int count){
        try {
            TempTx tf = tempTxMapper.selectByPrimaryKey(fromUserId);
            TempTx tt2 = tempTxMapper.selectByPrimaryKey(targetUserId);

            tf.setBlc(tf.getBlc() - count);
            tt2.setBlc(tt2.getBlc() + count);

            tempTxMapper.updateByPrimaryKey(tf);
            int x = 0;
            int y = 9 / x;
            tempTxMapper.updateByPrimaryKey(tt2);
        } catch (Exception e) {
            throw new RuntimeException();
        }
    }

    @Transactional
    public void transfer2(Long fromUserId, Long targetUserId, int count) {
        step1(fromUserId, count);
        step2(targetUserId,count);
    }

    private void step1(Long fromUserId , int count){
        TempTx tf = tempTxMapper.selectByPrimaryKey(fromUserId);
        tf.setBlc(tf.getBlc() - count);
        tempTxMapper.updateByPrimaryKey(tf);
    }

    private void step2(Long toUserId,int count){
        try {
            TempTx tt = tempTxMapper.selectByPrimaryKey(toUserId);
            tt.setBlc(tt.getBlc() + count);
            int m = 0;
            int n = 3/m;
            tempTxMapper.updateByPrimaryKey(tt);
        } catch (Exception e) {
            // 此处不抛出RuntimeExceptioin 或者其子
            // 就会破坏调用处的事务，也就是transfer2()方法的事务，一定要抛出RuntimeException异常
        }

    }
}
